package com.woniu.core.util;

import cn.hutool.core.util.ObjectUtil;
import com.woniu.core.exception.account.AccountException;
import com.woniu.core.exception.token.TokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.security.Key;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class JwtUtil {

    @Autowired
    private static StringRedisTemplate srt;

    /**
     * 自定义的秘钥
     */
    private static String sect = "";

    private static String adminSect = "asdgwergvdshjrtejhnsdfbsvserthbrtnbsrdngsrtgbsrdtnbtdhyyg";

    private static String userSect = "ksaasfdasdfadsfwfasdasfasdfdsfdsfasdfsafdlkfjlasjflfsghbdfghnbdfxgnfxgdhndfghksajfd";

    private static String coachSect = "rbsnbsrnfndfkjvbnevbasodfngdnfvoinrvlkernvxjbvlxknflkwnoi";

    private static String gymSect = "ncoierubglinsdofbvsldhfgklsdchnlsmhlgsuhncdfmgshdlfkghmcsd";

    /**
     * 生成token
     * @param body
     * @param mil
     * @return
     */
    public static String createToken(Map<String, Object> body, Integer mil ,Integer role) {
        if (role == 1) sect = adminSect;
        if (role == 2) sect = userSect;
        if (role == 3) sect = coachSect;
        if (role == 4) sect = gymSect;
        Key key = Keys.hmacShaKeyFor(sect.getBytes());
        JwtBuilder jwtBuilder = Jwts.builder();
        if (body == null || body.size() <= 0) throw new TokenException("Token为空",401);
        jwtBuilder.setClaims(body);
        if (mil == null) jwtBuilder.setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000));
        else jwtBuilder.setExpiration(new Date(System.currentTimeMillis() + mil * 60 * 1000));
        return jwtBuilder.signWith(key).compact();
    }

    /**
     * 生成token
     * @param body
     * @return
     */
    public static String createToken(Map<String, Object> body,Integer role) {
        if (role == 1) sect = adminSect;
        if (role == 2) sect = userSect;
        if (role == 3) sect = coachSect;
        if (role == 4) sect = gymSect;
        return createToken(body,null,role);
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public static Claims parseToken(String token,Integer role) {
        if (token==null) throw new TokenException("Token为空",401);
        if (role == 1) sect = adminSect;
        if (role == 2) sect = userSect;
        if (role == 3) sect = coachSect;
        if (role == 4) sect = gymSect;
        Key key = Keys.hmacShaKeyFor((sect.getBytes()));
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    }

    /**
     * 获取当前登录人id
     * @return
     */
    public static Integer getUserId(Integer role){
        System.out.println("JWT的role");
        System.out.println(role);
        String id = "";
        if (role==1) id = "adminId";
        else if (role==2) id = "userId";
        else if (role==3) id = "coachId";
        else id = "gymId";
        System.out.println("id是==============");
        System.out.println(id);
        String token = WebUtil.getRequest().getHeader("account_token");
        System.out.println("token"+token);
        //判断是否过期
        Claims maps = null;
        Integer userId = null;
        try {
            //当前token未过期，直接返回
            maps = JwtUtil.parseToken(token,role);
            userId = (Integer)maps.get(id);
        } catch (Exception e) {
            //旧的token过期了   解析longToken，获取storeId
            String longToken = srt.opsForValue().get(token);
            maps = JwtUtil.parseToken(longToken,role);
            userId = (Integer) maps.get(id);
        }
        System.out.println("userId是===========");
        System.out.println(userId);
        return userId;
    }

    /**
     * 获取IP地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        // 取用户ip地址
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
            if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ip = inet.getHostAddress();
            }
        }
        if(ip!=null && ip.length()>15){ //"***.***.***.***".length() = 15
            if(ip.indexOf(",")>0){
                ip = ip.substring(0,ip.indexOf(","));
            }
        }
        return ip;
    }


    /**
     * 根据身份证的号码算出当前身份证持有者的年龄
     *
     * @param
     * @throws Exception
     * @return  -1(表示异常) 0 (身份证号码为空)
     */
    public static Long getAgeForIdcard(String idcard) {
        try {
            Long age = 0L;
            if (ObjectUtil.isEmpty(idcard)) {
                return age;
            }

            String birth = "";
            if (idcard.length() == 18) {
                birth = idcard.substring(6, 14);
            } else if (idcard.length() == 15) {
                birth = "19" + idcard.substring(6, 12);
            }

            int year = Integer.valueOf(birth.substring(0, 4));
            int month = Integer.valueOf(birth.substring(4, 6));
            int day = Integer.valueOf(birth.substring(6));
            Calendar cal = Calendar.getInstance();
            age = Long.valueOf(cal.get(Calendar.YEAR) - year);
            //周岁计算
            if (cal.get(Calendar.MONTH) < (month - 1) || (cal.get(Calendar.MONTH) == (month - 1) && cal.get(Calendar.DATE) < day)) {
                age--;
            }
            return age;
        } catch (Exception e) {
            e.getMessage();
        }
        return -1L;
    }

    /**
     * 获取性别
     *         0=未知的性别,9=未说明的性别,2=女性,1=男性
     * @return int
     */
    public static String getSexFromIdCard(String idCard) {
        String sex = "";
        // 身份证号码为空
        if (idCard == "" || idCard.length() <= 0){
            throw new AccountException("身份证号为空",60000);
        }
        if (idCard.length() == 18) {
            if (Integer.parseInt(idCard.substring(16).substring(0, 1)) % 2 == 0) {// 判断性别
                sex = "女";
            } else {
                sex = "男";
            }
        } else if (idCard.length() == 15) {
            String usex = idCard.substring(14, 15);// 用户的性别
            if (Integer.parseInt(usex) % 2 == 0) {
                sex = "女";
            } else {
                sex = "男";
            }
        }
        return sex;
    }

    /**
     * 实名认证
     * @param cardId
     * @param realName
     * @return
     */
    public static String realNameAuthentication(String cardId,String realName){
        String host = "https://idcert.market.alicloudapi.com"; // 【1】请求地址 支持http 和 https 及 WEBSOCKET
        String path = "/idcard";// 【2】后缀
        String appcode = "3ff9e3d8db924f958a9552351908722e"; // 【3】开通服务后 买家中心-查看AppCode
        String idCard = cardId;// 【4】请求参数，详见文档描述
        String name = realName;// 【4】请求参数，详见文档描述
        try {
            String urlSend = host + path + "?idCard=" + idCard + "&name="+ URLEncoder.encode(name, "UTF-8");// 【5】拼接请求链接
            URL url = new URL(urlSend);
            HttpURLConnection httpURLCon = (HttpURLConnection) url.openConnection();
            httpURLCon.setRequestProperty("Authorization", "APPCODE " + appcode);//格式Authorization:APPCODE (中间是英文空格)
            int httpCode = httpURLCon.getResponseCode();
            if (httpCode == 200) {
                String json = read(httpURLCon.getInputStream());
                System.out.println("正常请求计费(其他均不计费)");
                System.out.println("获取返回的json：");
                System.out.print(json);
                int index = json.lastIndexOf("status");
                String str = json.substring(index + 9, index + 11);
                if (!str.equals("01")) return "实名认证失败，请重试";
            } else {
                Map<String, List<String>> map = httpURLCon.getHeaderFields();
                String error = map.get("X-Ca-Error-Message").get(0);
                if (httpCode == 400 && error.equals("Invalid AppCode `not exists`")) {
                    System.out.println("AppCode错误");
                    return "AppCode错误 ";
                } else if (httpCode == 400 && error.equals("Invalid Url")) {
                    System.out.println("请求的 Method、Path 或者环境错误");
                    return "请求的 Method、Path 或者环境错误 ";
                } else if (httpCode == 400 && error.equals("Invalid Param Location")) {
                    System.out.println("参数错误");
                    return "参数错误 ";
                } else if (httpCode == 403 && error.equals("Unauthorized")) {
                    System.out.println("服务未被授权（或URL和Path不正确）");
                    return "服务未被授权（或URL和Path不正确）";
                } else if (httpCode == 403 && error.equals("Quota Exhausted")) {
                    System.out.println("套餐包次数用完 ");
                    return "套餐包次数用完 ";
                } else if (httpCode == 403 && error.equals("Api Market Subscription quota exhausted")) {
                    System.out.println("套餐包次数用完，请续购套餐");
                    return "套餐包次数用完，请续购套餐 ";
                } else {
                    System.out.println("参数名错误 或 其他错误");
                    System.out.println(error);
                    return "参数名错误 或 其他错误 ";
                }
            }
        } catch (MalformedURLException e) {
            System.out.println("URL格式错误");
            return "URL格式错误";
        } catch (UnknownHostException e) {
            System.out.println("URL地址错误");
            return "URL地址错误";
        } catch (Exception e) {
            // 打开注释查看详细报错异常信息
            e.printStackTrace();
            return "实名认证失败";
        }
        return "true";
    }

    private static String read(InputStream is) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = br.readLine()) != null) {
            line = new String(line.getBytes(), "utf-8");
            sb.append(line);
        }
        br.close();
        return sb.toString();
    }

    public static boolean isChineseInput(String input) {
        String pattern = "[\\u4e00-\\u9fa5]+";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(input);
        return m.matches();
    }

    public static boolean isNumeric2(String str) {
        return str != null && str.matches("-?\\d+(\\.\\d+)?");
    }

}
